{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center>\n",
    "<img src=\"https://habrastorage.org/web/677/8e1/337/6778e1337c3d4b159d7e99df94227cb2.jpg\"/>\n",
    "## Специализация \"Машинное обучение и анализ данных\"\n",
    "<center>Автор материала: программист-исследователь Mail.Ru Group, старший преподаватель Факультета Компьютерных Наук ВШЭ [Юрий Кашницкий](https://yorko.github.io/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# <center>  Capstone проект №1 <br> Идентификация пользователей по посещенным веб-страницам\n",
    "<img src='http://i.istockimg.com/file_thumbview_approve/21546327/5/stock-illustration-21546327-identification-de-l-utilisateur.jpg'>\n",
    "\n",
    "# <center>Неделя 3. Визуальный анализ данных и построение признаков\n",
    "\n",
    "На 3 неделе мы займемся визуальным анализом данных и построением признаков. Сначала мы вместе построим и проанализируем несколько признаков, потом Вы сможете сами придумать и описать различные признаки. \n",
    "\n",
    "**План 3 недели:**\n",
    " - Часть 1. Построение признаков\n",
    " - Часть 2. Визуальный анализ данных\n",
    " - Часть 3. Дальнейшее построение признаков\n",
    " - Часть 4. Проверка построенных признаков\n",
    "\n",
    "**В этой части проекта Вам могут быть полезны видеозаписи следующих лекций курса \"Поиск структуры в данных\":**\n",
    "   - [Задача визуализации](https://www.coursera.org/learn/unsupervised-learning/lecture/hlvlT/zadacha-vizualizatsii)\n",
    "   - [Визуализация данных в sklearn](https://www.coursera.org/learn/unsupervised-learning/lecture/ityMo/vizualizatsiia-dannykh-v-sklearn)\n",
    "   \n",
    "**Также в задании будет использоваться библиотека Seaborn (ее можно дополнительно установить командой *pip install seaborn*), будет полезно обращаться к документациям [Matplotlib](http://matplotlib.org/users/) и [Seaborn](http://seaborn.pydata.org/), а также к примерам визуализации, описанным на StackOverflow.**\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Задание\n",
    "1. Заполните код в этой тетрадке \n",
    "2. Если вы проходите специализацию Яндеса и МФТИ, пошлите тетрадку в соответствующем Peer Review. <br> Если вы проходите курс ODS, выберите ответы в [веб-форме](https://docs.google.com/forms/d/1EbjK7-hF-Gepi6RH-K5I2XeiYGRoY0LNDx03QmLu9Xo). "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Часть 1. Построение признаков"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import division, print_function\n",
    "# отключим всякие предупреждения Anaconda\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "from glob import glob\n",
    "import os\n",
    "from tqdm import tqdm_notebook\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "pd.set_option('display.max.columns', 25)\n",
    "import pickle\n",
    "#pip install seaborn\n",
    "import seaborn as sns\n",
    "%matplotlib inline\n",
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Поменяйте на свой путь к данным\n",
    "PATH_TO_DATA = 'capstone_user_identification'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Создайте на основе функций *prepare_train_set* и *prepare_sparse_train_set_window*  новую – *prepare_train_set_with_fe*, (от \"feature engineering\"), создайте следующие признаки:**\n",
    "- `session_timespan` – продолжительность сессии (разница между максимальным и минимальным временем посещения сайтов в сессии, в секундах)\n",
    "- `#unique_sites` – число уникальных сайтов в сессии \n",
    "- `start_hour` – час начала сессии (то есть час в записи минимального timestamp среди десяти)\n",
    "- `day_of_week` – день недели (то есть день недели в записи минимального timestamp среди десяти)\n",
    "\n",
    "Функция должна возвращать новый DataFrame (как возвращала функция *prepare_train_set*), только признаков должно быть на 4 больше. Порядок, в котором добавляются признаки: *site1*, ... *site10*, *session_timespan*, *#unique_sites*, *start_hour*, *day_of_week* и *user_id* (это видно и чуть ниже по тому, как функция вызывается)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def prepare_train_set_with_fe(path_to_csv_files, site_freq_path, feature_names,\n",
    "                                    session_length=10, window_size=10):\n",
    "    ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Проверим функцию на игрушечном примере.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_names = ['site' + str(i) for i in range(1,11)] + \\\n",
    "                ['time_diff' + str(j) for j in range(1,10)] + \\\n",
    "                ['session_timespan', '#unique_sites', 'start_hour', \n",
    "                 'day_of_week', 'target']\n",
    "train_data_toy  = prepare_train_set_with_fe(os.path.join(PATH_TO_DATA, \n",
    "                                                         '3users'), \n",
    "                  site_freq_path=os.path.join(PATH_TO_DATA, \n",
    "                                              'site_freq_3users.pkl'),\n",
    "                  feature_names=feature_names, session_length=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_toy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Примените функцию *prepare_train_set_with_fe* к данным по 10 пользователям, укажите *session_length*=10.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "train_data_10users = prepare_train_set_with_fe ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_10users.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Примените функцию *prepare_train_set_with_fe* к данным по 150 пользователям, укажите *session_length*=10.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "train_data_150users = prepare_train_set_with_fe  ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Сохраните в pickle-файлы признаки *session_timespan*, *#unique_sites*, *start_hour* и *day_of_week* для 10 и 150 пользователей.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_features_10users = ''' ВАШ КОД ЗДЕСЬ '''\n",
    "new_features_150users = ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(PATH_TO_DATA, \n",
    "                       'new_features_10users.pkl'), 'wb') as new_features_10users_pkl:\n",
    "    pickle.dump(new_features_10users, new_features_10users_pkl)\n",
    "with open(os.path.join(PATH_TO_DATA, \n",
    "                       'new_features_150users.pkl'), 'wb') as new_features_150users_pkl:\n",
    "    pickle.dump(new_features_150users, new_features_150users_pkl)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**<font color='red'>Вопрос 1. </font> Выведите медианную продолжительность сессии (*session_timespan*) для сессий 10 пользователей.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**<font color='red'>Вопрос 2. </font> Выведите медианный день недели, в который началась сессия, для сессий 10 пользователей.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**<font color='red'>Вопрос 3. </font>Выведите медианный час начала сессии для сессий 150 пользователей.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**<font color='red'>Вопрос 4. </font>Выведите медианное значение числа уникальных сайтов в сессиях 150 пользователей.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Часть 2. Визуальный анализ данных"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Забавы ради, потехи для дадим пользователям имена и ассоциируем с ними цвета.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "id_name_dict = {128: 'Mary-Kate', 39: 'Ashley', 207: 'Lindsey', 127: 'Naomi', 237: 'Avril',\n",
    "               33: 'Bob', 50: 'Bill', 31: 'John', 100: 'Dick', 241: 'Ed'}\n",
    "train_data_10users['target'] = train_data_10users['target'].map(id_name_dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "color_dic = {'Mary-Kate': 'pink', 'Ashley': 'darkviolet', 'Lindsey':'blueviolet', \n",
    "             'Naomi': 'hotpink', 'Avril': 'orchid', \n",
    "             'Bob': 'firebrick', 'Bill': 'gold', 'John': 'forestgreen', \n",
    "             'Dick': 'slategrey', 'Ed':'brown'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1. Постройте гистограмму распределения длины сессии в секундах (*session_timespan*). Ограничьте по *x* значением 200 (иначе слишком тяжелый хвост). Сделайте гистограмму цвета *darkviolet*, подпишите оси по-русски.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_10users['session_timespan']  ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2. Постройте гистограмму распределения числа уникальных сайтов в сессии (*#unique_sites*). Сделайте гистограмму цвета *aqua*, подпишите оси по-русски.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_10users['#unique_sites']  ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3. Постройте гистограммы распределения числа уникальных сайтов в сессии (*#unique_sites*) для каждого из 10 пользователей по отдельности. Используйте *subplots*, чтоб разместить все 10 картинок на одной большой. Пометьте легендой каждую картинку, на легенде должно быть написано имя пользователя. Для каждого пользователя раскрасьте гистограмму его/ее цветом (*color_dic*). Подпишите оси по-русски в каждой из 10 гистограмм.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(16, 10))\n",
    "\n",
    "# как вариант, можно и по-другому\n",
    "for idx, (user, sub_df) in  enumerate(pd.groupby(train_data_10users, 'user_id')): \n",
    "     ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**4. Постройте гистограмму распределения часа начала сессии (*start_hour*). Сделайте гистограмму цвета *darkgreen*, подпишите оси по-русски.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_10users['start_hour'] ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**5. Постройте гистограммы распределения часа начала сессии (*start_hour*) для каждого из 10 пользователей по отдельности. Используйте *subplots*, чтоб разместить все 10 картинок на одной большой. Пометьте легендой каждую картинку, на легенде должно быть написано имя пользователя. Для каждого пользователя раскрасьте гистограмму его/ее цветом (*color_dic*). Подпишите оси по-русски в каждой из 10 гистограмм.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(16, 10))\n",
    "\n",
    "# как вариант, можно и по-другому\n",
    "for idx, (user, sub_df) in  enumerate(pd.groupby(train_data_10users, 'user_id')): \n",
    "     ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**6. Постройте гистограмму распределения дня недели, в который началась сессия (*day_of_week*). Сделайте гистограмму цвета *sienna*, подпишите оси по-русски.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_10users['day_of_week'] ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**7. Постройте гистограммы распределения дня недели, в который началась сессия (*day_of_week*) для каждого из 10 пользователей по отдельности. Используйте *subplots*, чтоб разместить все 10 картинок на одной большой. Измените метки по оси *X* на ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'] – метод *set_xticklabels*. Пометьте легендой каждую картинку, на легенде должно быть написано имя пользователя. Для каждого пользователя раскрасьте гистограмму его/ее цветом (*color_dic*). Подпишите по-русски название каждой из 10 гистограмм.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(16, 10))\n",
    "\n",
    "# как вариант, можно и по-другому\n",
    "for idx, (user, sub_df) in  enumerate(pd.groupby(train_data_10users, 'user_id')): \n",
    "     ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**8. Сделайте выводы про каждого пользователя по построенным графикам.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "''' ВАШЕ ОПИСАНИЕ ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Загрузите сохраненный ранее в pickle-файл частотный словарь сайтов для 10 пользователей. **"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Определите топ-10 самых посещаемых сайтов (*top10_sites*) и соответствующие кол-ва посещений (*top10_freqs*).**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "top10_freqs = ''' ВАШ КОД ЗДЕСЬ '''\n",
    "top10_sites = ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**9. Нарисуйте *seaborn barplot*, показывающий частоты посещений топ-10 сайтов. Сделайте подписи сайтов вертикальными, иначе они сливаются (*xticks*).**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.barplot ''' ВАШ КОД ЗДЕСЬ '''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Часть 3. Дальнейшее построение признаков"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Это задание творческое, тут надо придумать, как еще учесть время посещения веб-страниц и прочие признаки. \n",
    "\n",
    "На следующей неделе мы будем использовать \"мешок\" сайтов  для классификации сессий по принадлежности разным пользователям, а эти новые признаки, которые Вы сейчас создадите, потом добавим и посмотрим, улучшается ли модель. Поэтому можно их создать в виде отдельных матриц и сохранить их также отдельно.  \n",
    "\n",
    "В этой части задания Вы можете построить и визуально исследовать самые разные признаки (ничто фантазию не ограничивает):\n",
    "- год, месяц и день начала сессии\n",
    "- час начала сессии (с учетом года, месяца и дня)\n",
    "- время суток\n",
    "- среднее время пребывания на сайте, посчитать можно, скажем, для топ-30 популярных сайтов\n",
    "- индикаторы посещения популярных сайтов (скажем, тоже для топ-30 популярных сайтов)\n",
    "- частота посещения Facebook\n",
    "- ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Напишите функцию для создания новых признаков и примените ее к исходным данным – каталогам с 10 и 150 файлами. Сделайте это только для набора данных, полученного с параметрами *session_length=10* и *window_size=10*. Сериализуйте полученные матрицы с помощью pickle. Функция может возвращать как только новые признаки, так и старые с новыми. При этом сигнатура функции может быть другой – тут уже свобода выбора.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def feature_engineering(path_to_csv_files, features, session_length=10):\n",
    "    '''\n",
    "    ВАШ КОД ЗДЕСЬ\n",
    "    ''' "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_features_10users = feature_engineering ''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_features_150users = feature_engineering ''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**10. Постройте картинки для новых признаков, поисследуйте их, прокомментируйте результаты.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**В конце сохраните в pickle-файлы только те признаки, которые, как Вы предполагаете, помогут идентифицировать пользователя более точно. Это касается и признаков, которые мы вместе создали в начале (*session_timespan, #unique_sites, start_hour, day_of_week*), и Ваших собственных. Можно создать все эти признаки не только для сессий из 10 сайтов, но и для других сочетаний параметров *session_length* и *window_size*.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "selected_features_10users = ''' ВАШ КОД ЗДЕСЬ ''' \n",
    "selected_features_150users = ''' ВАШ КОД ЗДЕСЬ ''' "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(PATH_TO_DATA, \n",
    "                       'selected_features_10users.pkl'), 'wb') as selected_features_10users_pkl:\n",
    "    pickle.dump(selected_features_10users, selected_features_10users_pkl, \n",
    "                protocol=2)\n",
    "with open(os.path.join(PATH_TO_DATA, \n",
    "                       'selected_features_150users.pkl'), 'wb') as selected_features_150users_pkl:\n",
    "    pickle.dump(selected_features_150users, selected_features_150users_pkl, \n",
    "                protocol=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Критерии оценки работы (только для Peer Review в специализации):\n",
    "- Верно ли отображена гистограмма session_timespan из п. 1? (max. 3 балла)\n",
    "- Верно ли отображена гистограмма #unique_sites из п. 2? (max. 3 балла)\n",
    "- Верно ли отображены гистограммы #unique_sites по каждому пользователю из п. 3? (max. 6 баллов)\n",
    "- Верно ли отображена гистограмма start_hour из п. 4? (max. 3 балла)\n",
    "- Верно ли отображены гистограммы start_hour по каждому пользователю из п. 5? (max. 6 баллов)\n",
    "- Верно ли отображена гистограмма day_of_week из п. 6? (max. 3 балла)\n",
    "- Верно ли отображены гистограммы day_of_week по каждому пользователю из п. 7? (max. 6 баллов)\n",
    "- Насколько сделанные выводы в п. 8 соответствуют построенным картинкам? (max. 6 баллов)\n",
    "- Верно ли отображен barplot для 10 популярных сайтов из п. 9? (max. 6 баллов)\n",
    "- Правильно ли посчитана медианная продолжительность сессий в п. 10? (max. 3 балла)\n",
    "- Правильно ли посчитан медианный день недели начала сессии в п. 11? (max. 3 балла)\n",
    "- Правильно ли посчитан медианный час начала сессии в п. 12? (max. 3 балла)\n",
    "- Правильно ли посчитано медианное значение числа уникальных сайтов в сессиях 150 пользователей п. 13? (max. 3 балла)\n",
    "- Есть ли оригинальные построенные признаки и картинки к ним? Оцените также и качество картинок. (max. 8 баллов)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Пути улучшения\n",
    "Что еще можно добавить по 3 части проекта:\n",
    "- IPython-widgets, интерактив и анимация (стоящие статьи по этому ремеслу – [раз](https://habrahabr.ru/post/308162/) и  [два](https://habrahabr.ru/company/ods/blog/323210/))\n",
    "- можно попробовать изобразить исходные данные в некотором пространстве, например, Word2Vec, потом выделить главные компоненты или t-SNE  (только пользуйтесь эффективными реализациями типа [Multicore-TSNE](https://github.com/DmitryUlyanov/Multicore-TSNE), не Sklearn) и раскрасить по целевому классу. Но нет гарантий, что получится что-то значимо отличающееся от каши\n",
    "\n",
    "На следующей неделе мы наконец приступим к обучению моделей классификации. "
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
